﻿using Prism.Commands;
using Prism.Navigation;
using Prism.Regions;
using Quartz;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ZYing.QPanel.ViewModels
{
    public class ExecutionsViewModel : NavigationViewModelBase
    {
        public ExecutionsViewModel(IScheduler scheduler)
        {
            Scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler));
            this.ReloadCommand = new DelegateCommand(async () => await Reload());
            this.ReloadCommand.Execute();
            Run(this.CancellationTokenSource.Token);
        }

        private string _keyword;

        public string Keyword
        {
            get { return _keyword; }
            set { SetProperty(ref _keyword, value); }
        }
        public IScheduler Scheduler { get; }

        public ObservableCollection<JobExecutionItemViewModel> Executions { get; } = new ObservableCollection<JobExecutionItemViewModel>();
        public DelegateCommand ReloadCommand { get; }
        public async Task Reload()
        {
            var executions = await this.Scheduler.GetCurrentlyExecutingJobs();
            var dic = this.Executions.ToDictionary(i => i.Id, i => i);
            foreach (var item in executions)
            {
                if (!string.IsNullOrWhiteSpace(this.Keyword))
                {
                    var key = $"{item.JobDetail.Key.Name}_{item.JobDetail.Key.Group}_{item.Trigger.Key.Name}_{item.Trigger.Key.Group}_{item.JobDetail.JobType.FullName}";
                    if (key.IndexOf(this.Keyword, StringComparison.OrdinalIgnoreCase) == -1)
                    {
                        continue;
                    }
                }
                if (dic.TryGetValue(item.FireInstanceId, out var vm))
                {
                    await vm.RefreshStatus(item);
                    dic.Remove(item.FireInstanceId);
                }
                else
                {
                    vm = new JobExecutionItemViewModel(this.Scheduler, item);
                    this.Executions.Add(vm);
                }
            }

            if (dic.Count > 0)
            {
                foreach (var item in dic.Values)
                {
                    this.Executions.Remove(item);
                }
            }
        }
        private async void Run(CancellationToken cancellationToken)
        {
            while (true)
            {
                if (cancellationToken.IsCancellationRequested) break;
                if (this.IsActive)
                {
                    try
                    {
                        await Reload();
                    }
                    catch (Exception e)
                    {
                        Trace.WriteLine(e);
                    }
                }
                await Task.Delay(1000);
            }
        }
    }
}
